<?php
/**
 * 总控制器
 */
namespace app\common\controller;

use app\BaseController;
use think\facade\Filesystem;
use think\facade\Request;

class CommonBase extends BaseController
{
	public $errorMsg = '操作失败';

    // 初始化
    protected function initialize()
    {
        parent::initialize();
		$this->params = Request::param('', null, 'strip_tags,htmlspecialchars,addslashes,trim');
		$this->params['page'] = $this->params['page'] ?? 10;
		$this->params['limit'] = $this->params['limit'] ?? 10;
    }
    
    /**
     * 空操作
	 */
    public function __call($name, $arguments)
    {
        return $this->returnJsonData($name);
    }

    protected function returnJsonData($method = '', $isValidate = false)
    {
        $this->getAnyNamespacePath($method);

		// 开启场景验证
		if ( ! $this->checkValidateScene($isValidate)) {
			return getErrorJson($this->errorMsg);
		}

        // 判断逻辑层文件 
        if ( ! class_exists($this->logicClassPath) && ! $this->checkErrorLogicClass($method)) {
			return get404Content();
        }

		// 创建logic象
        $logic = new $this->logicClassPath($this->defaultModel ?? null);

		// 判断类方法
		if ( ! method_exists($logic, $method)) {
			return get404Content();
		}

		// 在执行函数前，执行业务逻辑检查操作
		if ( ! $res = $this->checkBusinessLogic($logic, $method)) {
			return $this->getErrorJsonFromService($logic);
		}

        $res = call_user_func(array($logic, $method), $this->params);
		// 直接返回结果
		if ( ! empty($logic->returnResult)) {
			return $res;
		}

		// 返回错误
        if ($res === false) 
			return $this->getErrorJsonFromService($logic);
		else
			// 成功返回
			return $this->getSuccessJsonFromService($logic, $res);
	}

    protected function getAnyNamespacePath($scene = '')
    {
        $module = strtolower(app('http')->getName());
		$controller = Request::controller();
        if (strpos($controller, '.') !== false) {
            $arr = explode('.', $controller);
            $controller = strtolower($arr[0])."\\".ucfirst($arr[1]);
			// 2级控制器
			$controller2 = ucfirst($arr[1]);
			$this->modelClassPath = "app\\common\\model\\{$controller2}Model";
		}

        $this->logicClassPath = "app\\{$module}\\logic\\{$controller}";
        $this->errorLogicClassPath = "app\\{$module}\\logic\\Error";
        $this->validateScenePath = "app\\{$module}\\validate\\{$controller}.{$scene}";
    }

	protected function checkValidateScene($isValidate)
	{
		if ($this->isValidateScene($isValidate)) {
			try {
				// 验证数据
                $result = $this->validate($this->params, $this->validateScenePath);
            } catch (\Exception $e) {
				// 验证失败 输出错误信息
                $result = $e->getMessage();
            }

			// 验证失败 输出错误信息
			if(true !== $result){
				$this->errorMsg = $result;
				return false;
			}
		}

		return true;
	}

	protected function checkErrorLogicClass($method)
	{
		// 后台默认的功能
		if (class_exists($this->errorLogicClassPath) && class_exists($this->modelClassPath) && in_array($method, ['getList', 'save', 'delete'])) {
			$this->logicClassPath = $this->errorLogicClassPath;
			$this->defaultModel = $this->modelClassPath;

			return true;
		}

		return false;
	}

	protected function isValidateScene($isValidate)
	{
		if ( ! $isValidate) {
			$arr = explode('.',$this->validateScenePath);
			if ( ! empty($arr) && is_array($arr) && count($arr) == 2 && class_exists($arr[0])) {
				$validateClass = $arr[0];
				$validateMethod = $arr[1];
				$myValidate = new $validateClass();
				if ($myValidate->checkSceneIsExist($validateMethod)) {
					$isValidate = true;
				}
			}
		}

		return $isValidate;
	}

	/**
	 * 在执行函数前，执行检查操作
	 * 格式：public _check{Method}
	 */
	protected function checkBusinessLogic($logic, $method)
	{
		$checkMethod = '_check'.ucfirst($method);
		if (method_exists($logic, $checkMethod)) {
			$foo = new \ReflectionMethod($logic, $checkMethod);
			$s = \Reflection::getModifierNames($foo->getModifiers());
			if ( ! empty($s) && ! empty($s[0]) && $s[0] == 'public') {
				$res = call_user_func(array($logic, $checkMethod), $this->params);
				if ($res === false) return false;

				// 返回params
				if ( ! empty($res) && is_array($res)) 
					$this->params = $res;
			}
		}

		return true;
	}

	protected function getErrorJsonFromService($logic)
    {
		return getJson(
			$logic->returnCode ?? 201,
			$logic->returnMsg ?? ($logic->errorMsg ?? $this->errorMsg),
			$logic->returnData ?? null
		);
	}

	protected function getSuccessJsonFromService($logic, $data)
    {
		return getJson(
			$logic->returnCode ?? 200,
			$logic->returnMsg ?? '操作成功',
			$logic->returnData ?? $data
		);
	}
}